package com.wpx.log.core.aspect;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.wpx.log.core.LogContext;
import com.wpx.log.core.LogRequestContext;
import com.wpx.log.core.after.IAfter;
import com.wpx.log.core.before.IBefore;


/**
 * 	切入处理日志
 * @author 韦鹏香
 * @date 2020/05/02
 */
@Aspect
@EnableAsync
public class LogAspect {
	
	private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
	
	@Autowired
	private HttpServletRequest request;
	
	@Autowired
	private LogContext logContext;
	
	@Autowired
	private DoHandler doHandler;
	
	@Autowired
	private List<IBefore> befores = new ArrayList<IBefore>();
	
	@Autowired
	private List<IAfter> afters = new ArrayList<IAfter>();
	
	@Pointcut("@annotation(com.wpx.log.core.annotation.OpLog)")
	public void logPointCut() {}
	
	
	@Around("logPointCut()")
	public Object around(ProceedingJoinPoint point) throws Throwable {
		
		Object returnObj = null;
		Object logObj = null;
		LogRequestContext requestContext = new LogRequestContext(request, point);		
		befores.forEach(before -> before.execute(logContext, requestContext, point));
		try {
			logObj = this.logContext.getLogClass().newInstance();
			if(requestContext.isIpPass()) {
				returnObj = point.proceed();
			}
			requestContext.setReturnObj(returnObj);
			afters.forEach(after -> after.execute(logContext, requestContext, point));
			return returnObj;
		} catch (Throwable e) {
			requestContext.setException(e);
			e.printStackTrace();
			throw e;
		}finally {
			doHandler.doAsyncLogHandler(requestContext, logObj);
			ServletRequestAttributes servletRequestAttributes =(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
			RequestContextHolder.setRequestAttributes(servletRequestAttributes,true);
			
			doHandler.doLogHandler(requestContext, logObj);
		}

	}
	
	
}
